home *** CD-ROM | disk | FTP | other *** search
- /**********************************************************************
- NOTE: MSET follows the memory control block chain to find the first
- copy of COMMAND.COM. This technique works reliably only with
- DOS 3.3 and earlier. For a much better way to set things in the
- master environment, see Andrew Schulman's "Undocumented DOS".
- ************************************************************************/
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <dos.h>
- #include <string.h>
-
- #include "lantasti.h"
-
- #define MK_FP(seg,ofs) ((void far *) \
- (((unsigned long)(seg) << 16) | (unsigned)(ofs)))
-
-
- /* psp and memory control structures */
- typedef struct {
- char misc1[22];
- unsigned int parent_seg;
- char misc2[20];
- unsigned int env_seg;
- } PSP;
-
- typedef struct {
- char status; /* block currently in use? */
- unsigned int owners_psp; /* segment of owner's PSP */
- unsigned int size; /* in paragraphs */
- } MCB;
-
- /* global environment info */
- char far *par_env;
- int par_env_len;
-
- /* get_parent_envp **********************************************************
- Returns a pointer to the calling process' environment block
- *****************************************************************************/
- void get_parent_envp()
- {
- union REGS regs;
- struct SREGS sregs;
-
- PSP far *cmd_psp;
- MCB far *cmd_mcb,far *env_mcb, far *config_mcb;
- int far *seg_ptr;
-
- regs.x.ax = 0x5200;
- intdosx(®s, ®s, &sregs);
-
- seg_ptr = MK_FP(sregs.es, regs.x.bx - 2);
- config_mcb = MK_FP(*seg_ptr, 0);
-
- cmd_psp = MK_FP(FP_SEG(config_mcb) + config_mcb->size + 2, 0);
-
- if (cmd_psp->env_seg == 0) {
- /* Environment is in block after parent program */
- cmd_mcb = MK_FP(FP_SEG(config_mcb) + config_mcb->size + 1, 0);
- par_env = MK_FP(FP_SEG(cmd_mcb) + cmd_mcb->size + 2, 0);
- }
- else /* We have pointer to environment */
- par_env = MK_FP(cmd_psp->env_seg, 0);
-
- /* MCB of environment is 1 segment lower */
-
- env_mcb = MK_FP(FP_SEG(par_env) - 1, 0);
-
- par_env_len = env_mcb->size * 16;
-
- }
-
- /* del_par_env ********************************************************************
-
- *****************************************************************************/
- void del_par_env(env_var)
- char *env_var;
- {
-
- char far *far1; /* Beginning of next variable */
- char far *far2; /* Beginning of the variable */
- char *str; /* env_var ptr used in search */
-
- int found = FALSE; /* End of search flag */
-
- far1 = par_env;
-
- while(*far1 && !found)
- { /* Find start of variable to delete */
- str = env_var;
- far2 = far1;
- for(;(*far1 == *str) && (*far1 != '=') && *far1 && *str; ++far1, ++str)
- ;
- if((!*str) && (*far1 == '='))
- found = TRUE; /* We found it! */
- for(; *far1; ++far1)
- ;
- ++far1;
- }
-
- if(!*far1 && !found) /* Find env_var? */
- return; /* No, we didn't */
-
- /* Shift environment down, to cover env_var */
-
- for(; !(!*far1 && !*(far1+1)); *far2++ = *far1++)
- ;
-
- *far2 = 0; /* End env with 2 nulls */
- ++far2;
- *far2 = 0;
- }
-
- /* put_par_env ********************************************************************
-
- *****************************************************************************/
- void put_par_env(env_var,env_text)
- char far *env_var,*env_text;
- {
-
- char far *far0;
- int len;
- char env_str[256];
- char *str;
-
- /* build environment string */
- strcpy(env_str, env_var);
- strcat(env_str, "=");
- strcat(env_str, env_text);
-
- /* delete old environment variable */
- del_par_env(env_var);
-
- /* Find end of environment by looking for 2 NULLS */
- for(far0 = par_env, len = 0; !(!*far0 && !*(far0+1)); ++far0, ++len)
- ;
-
- /* get amount of remaining free space in env. block */
- len = par_env_len - (len + 2);
-
- if(len < strlen(env_str) + 1)
- { /* If out of room, return error */
- puts("Out of environment space.");
- return;
- }
-
- str = env_str;
-
- /* add new variable to end of environment */
- for(++far0; *str; *far0++ = *str++)
- ;
-
- /* terminate with two nulls */
- *far0 = 0;
- ++far0;
- *far0 = 0;
-
- }
-
- /* ********************************************************************
- MSET - Sets a variable in the lowest level (MASTER) environment.
- *****************************************************************************/
- main(argc,argv)
- int argc;
- char *argv[];
- {
- int i;
- char vname[40],value[256];
- char *tok;
-
- if (argc < 2) {
- puts("MSET - Sets variables in the master environment.\n");
- puts("Usage: Same as the built in SET command -- for example");
- puts("MSET PATH=C:\;C:\UTILITY\n");
- puts("Copyright 1989 by SoftMagic, Inc. All rights reserved.");
- exit(0);
- }
-
- /* first, change the variable in the local environment */
- putenv(argv[1]);
-
- /* now change the master environment */
- tok = strtok(argv[1],"="); /* get the variable name */
- if (strlen(tok) > 39) {
- puts("Invalid variable name -- give me a break!");
- exit(-1);
- }
- else strcpy(vname,tok);
- strupr(vname);
-
- get_parent_envp();
-
- tok = strtok(NULL," ");
- if (tok == NULL) del_par_env(vname);
- else {
- strcpy(value,tok);
- for (i = 2;i < argc; i++) {
- strcat(value," ");
- strcat(value,argv[i]);
- }
- put_par_env(vname,value);
- }
-
- }
-